package com.doge.calcalbum.business.calc

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.doge.calcalbum.App
import com.doge.calcalbum.R
import com.doge.calcalbum.analysis.analysisEvent
import com.doge.calcalbum.analysis.pwd_success
import com.doge.calcalbum.business.LauncherActivity
import com.doge.calcalbum.business.calc.plugins.Calculator
import com.doge.calcalbum.business.guide.GuideCalcLayout
import com.doge.calcalbum.business.vip.VipBuyActivity
import com.doge.calcalbum.core.base.adapters.add
import com.doge.calcalbum.core.base.adapters.remove
import com.doge.calcalbum.utils.*
import kotlin.math.max

object CalcController {
    const val DOT = "."
    const val PLUS = "+"
    const val LESS = "-"
    const val MULTIPLY = "×"
    const val MULTIPLY_REAL = "*"
    const val DIVIDE = "÷"
    const val DIVIDE_REAL = "/"

    val output = MutableLiveData<String>()
    val history = MutableLiveData<List<String>>()
    val pwdTip = MutableLiveData<String?>()
    val hasPass: Boolean get() = hasPwd
    private var maxHistoryCount = 10
    private var hasCalc = false
    private var hasPwd = CalcPwdHelper.hasPwd
    private var tempPwd: String? = null
    private var resettingPwd = CalcPwdHelper.resettingPwd

    init {
        if (!hasPwd) pwdTip.value = getString(R.string.input_new_pwd)
        else if (resettingPwd) pwdTip.value = getString(R.string.input_old_pwd)
        log("calc viewModel init hasPwd $hasPwd resettingPwd $resettingPwd")
    }

    fun c() {
        output.value = ""
    }

    fun delete() {
        val value = output.value
        if (value?.isNotEmpty() == true) {
            output.value = value.substring(0, value.length - 1)
        }
    }

    fun calc() {
        hasCalc = true
        val expression = output.value ?: ""
        if (expression.isEmpty()) return
        val realExpression =
            expression.replace(MULTIPLY, MULTIPLY_REAL).replace(DIVIDE, DIVIDE_REAL)
        val result: Double = Calculator.conversion(realExpression)
        val resultInt = result.toInt()
        val finalOutput = (if (result.compareTo(resultInt) == 0) resultInt else result).toString()
        recordHistory("${expression}=${finalOutput}")
        output.value = finalOutput
    }

    fun input(input: String) {
        var value = output.value ?: ""
//        if (hasCalc) value = ""

        // 不能起手 点.加.减.乘.除
        if (value.isEmpty() && (input == DOT || input == PLUS || input == LESS || input == MULTIPLY || input == DIVIDE)) return
        // 最多一个点
        if (input == DOT && value.contains(DOT)) return

        hasCalc = false
        output.value = "$value$input"
    }

    fun percent() {
        val value = output.value ?: ""
        if (value.isEmpty()) return

        if (!hasPwd) {
            when {
                tempPwd.isNullOrEmpty() -> {
                    pwdTip.value = getString(R.string.input_new_pwd_again)
                    tempPwd = value
                }
                tempPwd != value -> {
                    pwdTip.value = getString(R.string.input_new_pwd)
                    tempPwd = null
                    toast(R.string.input_new_pwd_error)
                }
                else -> {
                    CalcPwdHelper.set(value)
//                    toast(R.string.input_new_pwd_success_tip)
                    hasPwd = true
                    tempPwd = null
                    pwdTip.value = null

                    RemindPwdDialog.Builder(Activities.top!!)
                        .create().apply {
                            setOnDismissListener {
                                GuideCalcLayout.completed()
                                AppGuideUtils.remarkSetPwd()
                                notifyIntercept(false) // 设置新密码成功
                            }
                        }.show()
                }
            }
            output.value = ""
            return
        } else if (resettingPwd) {
            val checkResult = CalcPwdHelper.check(value)
            if (!checkResult) {
                toast(R.string.input_old_pwd_error)
            } else {
                CalcPwdHelper.resetCompleted()
                resettingPwd = false
                hasPwd = false
                tempPwd = null
                pwdTip.value = getString(R.string.input_new_pwd)
                // 旧密码验证成功.清除了密码
            }
            output.value = ""
            return
        } else if (CalcPwdHelper.check(value)) {
            notifyIntercept(false)
            output.value = ""
            analysisEvent(pwd_success)
            return // 解锁成功
        } else {
            toast(R.string.pwd_error)
            return // 密码错误
        }
//        if (value.contains(".")) return
//        val result: Double = (value.toDoubleOrNull() ?: 0.toDouble()) / 100
//        output.value = result.toString()
    }

    fun setMaxHistoryCount(count: Int) {
        log("setMaxHistoryCount $count")
        maxHistoryCount = max(1, count)
    }

    private fun recordHistory(value: String) {
        history.value = (history.value ?: listOf()).add(value).let {
            if (it.size > maxHistoryCount) it.remove(it.first()) else it
        }
    }

    fun notifyIntercept(boolean: Boolean?) {
        log("calc notifyIntercept $boolean")
        require(isMainThread())
        if (boolean == true) {
            val ignore = Activities.top is LauncherActivity ||
                    Activities.top is VipBuyActivity
            if (!ignore) {
                CalcActivity.start(Activities.top)
            }
        } else if (boolean == false) {
            Activities.finish(CalcActivity::class.java)
        }
    }

    fun resetPwd(forceClear: Boolean) {
        if (!forceClear) {
            tempPwd = null
            pwdTip.value = getString(R.string.input_old_pwd)
            CalcPwdHelper.reset()
            resettingPwd = true
            output.value = ""
            notifyIntercept(true)
        } else {
            CalcPwdHelper.resetCompleted()
            resettingPwd = false
            hasPwd = false
            tempPwd = null
            pwdTip.value = getString(R.string.input_new_pwd)
            output.value = ""
            notifyIntercept(true)
        }
    }

}